; void recortar_asm (
; 	unsigned char *src,
; 	unsigned char *dst,
; 	int m,
; 	int n,
; 	int src_row_size,
; 	int dst_row_size,
; 	int tam
; );

; Parámetros:
; 	rdi = src
; 	rsi = dst
; 	rdx = m
; 	rcx = n
; 	r8 = src_row_size
; 	r9 = dst_row_size
; 	rbp + 16 = tam


global recortar_asm

section .text

recortar_asm:

	push rbp
	mov rbp, rsp
	push rbx
        push r12 
        push r13
        push r14
        push r15

	xor r12, r12
	mov r12d, [rbp + 16]

	
	push rdi
	push rsi
	push rdx
	push rcx
	push r8
	push r9
	push r12
	

	; calculamos pos del cuadrante B en destino
	mov rax, r9
	mul r12					; TODO asumimos que rdx va a ser 0
	add rax, rsi
	; rax = dest + tam * dest_row_size 


	mov rsi, rax
	mov rdx, r12
	mov rax, rcx			; temporal
	mov rcx, r8
	mov r8, r9
	mov r9, rax
	
	call moverHemisferio			; norte = A y B

	pop r12
	pop r9
	pop r8
	pop rcx
	pop rdx
	pop rsi
	pop rdi

	mov rax, rdx
	sub rax, r12
	mul r8
	add rdi, rax			; calculamos puntero a hemisferio origen


	mov rdx, r12
	mov rax, rcx			; temporal
	mov rcx, r8
	mov r8, r9
	mov r9, rax
	

	call moverHemisferio			; sur = C y D


	pop r15
        pop r14
        pop r13
        pop r12
        pop rbx
	pop rbp


	ret


;void moverHemisferio(unsigned char* src, unsigned char* dest, int tam, int srcRowSize, int destRowSize, int sourceAncho)
moverHemisferio:
	push rbp
	mov rbp, rsp
	push rbx
        push r12 
        push r13
        push r14
        push r15


	mov r12, 0			; r12 : 
	mov r13, 0			; r13 : cantidad de filas copiadas
	mov r14, rdi
	add r14, r9			
	sub r14, rdx			; r14 = source + ancho source - tam
	mov r15, rsi
	add r15, rdx			; r15 = dest + tam
.moverCuadrante:
	
		mov r11, r12
		add r11, 16
		cmp r11, rdx
		jbe .moverDatos
		mov r12, rdx
		sub r12, 16

		.moverDatos:
		
		movups xmm0, [rdi + r12]		; movemos 16 bytes de A
		movups xmm1, [r14 + r12]		; movemos 16 bytes de B
		movups [rsi + r12], xmm1		; guardamos 16 bytes de B en destino
		movups [r15 + r12], xmm0		; guardamos 16 bytes de A en destino

		add r12, 16
		cmp r12, rdx
		jb .moverCuadrante
		je .siguienteFila
		
	.siguienteFila:
			mov r12, 0		; volvemos a empezar de la columna 0
			add rdi, rcx		; recalculamos source para A
			add r15, r8		; recalculamos dest para A

			add r14, rcx		; recalculamos source para B
			add rsi, r8		; recalculamos dest para B 

			; actualizamos filas
			inc r13
			cmp r13, rdx
			jge .moverCuadranteFin

			jmp .moverCuadrante

.moverCuadranteFin:

	pop r15
        pop r14
        pop r13
        pop r12
        pop rbx
	pop rbp


	ret




